package top.honlnk.czuan.common.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.PathContainer;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import top.honlnk.czuan.common.config.ConstantConfig;
import top.honlnk.czuan.common.utils.BitmaskUtil;
import top.honlnk.czuan.common.utils.JWTTokenUtil;
import top.honlnk.czuan.common.exception.CustomException;

import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class PowerInterceptor implements HandlerInterceptor {

    // 配置需要拦截的路径
    private final PathPattern userPattern = new PathPatternParser().parse("/api/user/**");
    private final PathPattern addPattern = new PathPatternParser().parse("/api/add/**");

    @Autowired
    private BitmaskUtil bitmaskUtil;

    @Autowired
    private ConstantConfig constantConfig;

    // 判断Token中的权限是否包含当前请求的权限
    @Override
    public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws CustomException {

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            // 这是一个预检请求，不记录日志，直接返回‘200’状态码
            response.setStatus(HttpStatus.OK.value());
            return true;
        }

        // 2. 获取token中存储的power信息
        Integer powerValue = Objects.requireNonNull(JWTTokenUtil.getCurrentUser()).getPower();
        log.info("user: {}", powerValue);

        // 3. 判断请求路径是什么
        // 3.1 判断是否是用户管理路径
        String path = request.getRequestURI();
        if (userPattern.matches(PathContainer.parsePath(path))) {
            bitmaskUtil.hasPermission(powerValue, constantConfig.getMANAGE_USERS_POWER());
        }
        // 3.2 判断是否是添加单词路径 必须同时拥有查看和添加权限
        if (addPattern.matches(PathContainer.parsePath(path))) {
            bitmaskUtil.hasPermissionOfNames(powerValue,
                    List.of(
                            constantConfig.getGET_POWER(),
                            constantConfig.getADD_POWER()
                    )
            );
        }


        return true;
    }
}
